package com.crm.websocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.crm.entity.User;
import com.crm.repository.MessageRepository;
import com.crm.repository.UserRepository;
import com.google.common.collect.Maps;

import lombok.extern.slf4j.Slf4j;

import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
@ServerEndpoint("/websocket/{uid}")
public class WebSocket {
    public  static  WebSocket webSocket;

    @Autowired 
    private UserRepository userRepository;

    @Autowired
    private MessageRepository messageRepository;
    private static final Logger log=org.slf4j.LoggerFactory.getLogger(WebSocket.class);
    @PostConstruct
    public  void init(){
        webSocket=this;
        webSocket.userRepository=this.userRepository;
    }
    /**
     * 在线人数
     */
    public static volatile AtomicInteger onlineNumber = new AtomicInteger(0);

    /**
     * 以用户的姓名为key，WebSocket为对象保存起来
     */
    private static Map<String, WebSocket> clients = new ConcurrentHashMap<>();

    /**
     * 会话
     */
    private Session session;

    /**
     * 用户名称
     */
    private String username;

    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("uid") String username, Session session)
    {
        User webSocketUname = webSocket.userRepository.findWebSocketUname(username);
        System.out.println(this);
        onlineNumber.addAndGet(1);
        log.info("现在来连接的客户id："+session.getId()+"用户名："+webSocketUname.getUserName());
        this.username = username;
        this.session = session;
        log.info("有新连接加入！ 当前在线人数" + onlineNumber);
        try {
            username=webSocketUname.getUserName();
            //messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
            //先给所有人发送通知，说我上线了
            Map<String,Object> map1 = Maps.newHashMap();
            map1.put("messageType",1);
            map1.put("username",username);
            sendMessageAll(JSON.toJSONString(map1),username);

            //把自己的信息加入到map当中去
            clients.put(username, this);
            //给自己发一条消息：告诉自己现在都有谁在线
            Map<String,Object> map2 = Maps.newHashMap();
            map2.put("messageType",3);
            //移除掉自己
            Set<String> set = clients.keySet();
            map2.put("onlineUsers",set);
            sendMessageTo(JSON.toJSONString(map2),username);
        }
        catch (IOException e){
            log.info(username+"上线的时候通知所有人发生了错误");
        }



    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.info("服务端发生了错误"+error.getMessage());
        //error.printStackTrace();
    }
    /**
     * 连接关闭
     */
    @OnClose
    public void onClose()
    {
        User webSocketUname = webSocket.userRepository.findWebSocketUname(username);
        onlineNumber.addAndGet(-1);
        //webSockets.remove(this);
        clients.remove(username);
        try {
            username=webSocketUname.getUserName();
            //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
            Map<String,Object> map1 = Maps.newHashMap();
            map1.put("messageType",2);
            map1.put("onlineUsers",clients.keySet());
            map1.put("username",username);
            sendMessageAll(JSON.toJSONString(map1),username);
        }
        catch (IOException e){
            log.info(username+"下线的时候通知所有人发生了错误");
        }
        log.info("有连接关闭！ 当前在线人数" + onlineNumber);
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session)
    {
        try {

            log.info("来自客户端消息：" + message+"客户端的id是："+session.getId());
            JSONObject jsonObject = JSON.parseObject(message);//转化为Object
            String textMessage = jsonObject.getString("message");
            String fromusername = jsonObject.getString("username");//获取object中username字段;   就是发送人字段
            String tousername = jsonObject.getString("to");//发给谁字段
            //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
            Map<String,Object> map1 = Maps.newHashMap();
            map1.put("messageType",4);
            map1.put("textMessage",textMessage);
            map1.put("fromusername",fromusername);
            if(tousername.equals("All")){
                map1.put("tousername","所有人");
                sendMessageAll(JSON.toJSONString(map1),fromusername);
            }
            else{//调用方法发送给改用户
                map1.put("tousername",tousername);
                User byUserName = webSocket.userRepository.findByUserName(fromusername);
                User byUserName1 = webSocket.userRepository.findByUserName(tousername);
              
              
                	if(clients.containsKey(tousername)) {
                		System.out.println(tousername);
                	}else {
                		  webSocket.messageRepository.addDyniMessage(textMessage,byUserName.getUserId(),byUserName1.getUserId());
                	}
                
              
                sendMessageTo(JSON.toJSONString(map1),tousername);
            }
        }
        catch (Exception e){
            log.info("发生了错误了");
        }

    }

    public void sendMessageTo(String message, String ToUserName) throws IOException {
        WebSocket webSocket = clients.get(ToUserName);
        webSocket.session.getBasicRemote().sendText(message);
//        for (WebSocket item : clients.values()) {
//            if (item.username.equals(ToUserName) ) {
//                item.session.getAsyncRemote().sendText(message);
//                break;
//            }
//        }
    }

    public void sendMessageAll(String message,String FromUserName) throws IOException {
        for (WebSocket item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }

    public static synchronized AtomicInteger getOnlineCount() {
        return onlineNumber;
    }
}
